﻿using System;
using System.Windows.Forms;
using CSW.Framework.Common;
using CSW.Framework.UI.Binding;

namespace CSW.Framework.UI.Binding
{
    /// <summary>
    /// A wrapper class for binding <see cref="CheckBox"/> objects.
    /// </summary>
    public class BindableCheckBox : IBindableControl
    {
        private readonly CheckBox m_CheckBox;
        private readonly bool m_AllowTabStop;

        /// <summary>
        /// Initializes a new instance of the <see cref="BindableCheckBox"/> class.
        /// </summary>
        /// <param name="checkBox">The <see cref="CheckBox"/> control to wrap.</param>
        public BindableCheckBox(CheckBox checkBox)
        {
            Guard.ArgumentNotNull(checkBox, "checkBox");

            m_CheckBox = checkBox;
            m_AllowTabStop = m_CheckBox.TabStop;
            m_CheckBox.CheckedChanged += CheckBox_CheckChanged;
        }

        private void CheckBox_CheckChanged(object sender, EventArgs e)
        {
            EventHandler tmpValidated = Validated;
            if (tmpValidated != null)
            {
                tmpValidated(sender, e);
            }
        }

        #region IBindableControl Members

        /// <summary>
        /// Occurs when the control has validated.
        /// </summary>
        public event EventHandler Validated;

        /// <summary>
        /// Sends the <see cref="Validated"/> event.
        /// </summary>
        public void SendValidated()
        {
            EventHandler validated = Validated;
            if (validated != null)
                validated(this, EventArgs.Empty);
        }

        /// <summary>
        /// Gets the control this object wraps.
        /// </summary>
        /// <value>The control this object wraps.</value>
        public Control Control
        {
            get { return m_CheckBox; }
        }

        /// <summary>
        /// Gets or sets the value of the control.
        /// </summary>
        /// <value>The value of the control.</value>
        public object Value
        {
            get { return m_CheckBox.Checked; }
            set { m_CheckBox.Checked = (value == null ? false : (bool)value); }
        }

        /// <summary>
        /// Gets the name of the control.
        /// </summary>
        /// <value>The name of the control.</value>
        public string Name
        {
            get { return m_CheckBox.Name; }
        }

        /// <summary>
        /// Gets or sets a value indicating whether the control is enabled.
        /// </summary>
        /// <value><c>true</c> if enabled; otherwise, <c>false</c>.</value>
        public bool Enabled
        {
            get { return m_CheckBox.Enabled; }
            set { m_CheckBox.Enabled = value; }
        }

        /// <summary>
        /// Gets or sets a value indicating whether the control is read only.
        /// </summary>
        /// <value><c>true</c> if read only; otherwise, <c>false</c>.</value>
        public bool ReadOnly
        {
            get { return !m_CheckBox.Enabled; }
            set
            {
                m_CheckBox.Enabled = !value;
                m_CheckBox.TabStop = !value && m_AllowTabStop;
            }
        }

        /// <summary>
        /// Focuses the control.
        /// </summary>
        public void Focus()
        {
            m_CheckBox.Focus();
        }

        /// <summary>
        /// Gets the tab index.
        /// </summary>
        /// <value>The tab index.</value>
        public int TabIndex
        {
            get { return m_CheckBox.TabIndex; }
        }

        /// <summary>
        /// Gets or sets the maximum string length.
        /// </summary>
        /// <value>The maximum string length.</value>
        public int MaxLength
        {
            get { throw new NotSupportedException("MaxLength is not supported."); }
            set { throw new NotSupportedException("MaxLength is not supported."); }
        }

        #endregion

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            Validated = null;
            m_CheckBox.CheckedChanged -= CheckBox_CheckChanged;
        }
    }
}